const { program } = require('commander');
const path = require('path');
const fs = require('fs').promises;
const axios = require('axios');
const readline = require('readline');

// 配置命令行选项
program
    .option('--host <host>', 'server host', '127.0.0.1')
    .option('--port <port>', 'server port', '8080')
    .option('--user <user>', 'username', 'zs')
    .option('--pwd <pwd>', 'password', 'ddd')
    .option('--help', 'display help');

program.parse(process.argv);
const options = program.opts();

// 显示帮助信息
if (options.help) {
    console.log(`
File Management System Client

Options:
    --host <host>    Server host (default: 127.0.0.1)
    --port <port>    Server port (default: 8080)
    --user <user>    Username (default: zs)
    --pwd <pwd>      Password (default: ddd)
    --help          Display this help message

Commands:
    upload <file>                     Upload local file to server
    download <file>                   Download file from server
    delete <file/dir>                 Delete file or directory
    rename <old-name> <new-name>      Rename file or directory
    mkdir <dir>                       Create new directory
    list                             List directory contents
    lcd <dir>                        Change local directory
    lpwd                             Print local working directory
    rcd <dir>                        Change remote directory
    rpwd                             Print remote working directory
    help                             Show this help message
    exit                             Exit the program
    `);
    process.exit(0);
}

// 创建 HTTP 客户端
const api = axios.create({
    baseURL: `http://${options.host}:${options.port}`,
    headers: {
        'Authorization': `Basic ${Buffer.from(`${options.user}:${options.pwd}`).toString('base64')}`,
        'Session-ID': Date.now().toString()
    }
});

// 命令处理函数
const commands = {
    async upload(filename) {
        if (!filename) {
            console.error('Error: Filename is required');
            return;
        }

        try {
            const filePath = path.join(process.cwd(), filename);
            const content = await fs.readFile(filePath);
            await api.post('/api/upload', {
                filename: path.basename(filename),
                content: content.toString('base64')
            });
            console.log('File uploaded successfully');
        } catch (error) {
            console.error('Upload failed:', error.response?.data?.error || error.message);
        }
    },

    async download(filename) {
        if (!filename) {
            console.error('Error: Filename is required');
            return;
        }

        try {
            const response = await api.get(`/api/download/${filename}`);
            const filePath = path.join(process.cwd(), filename);
            await fs.writeFile(filePath, Buffer.from(response.data.content, 'base64'));
            console.log('File downloaded successfully');
        } catch (error) {
            console.error('Download failed:', error.response?.data?.error || error.message);
        }
    },

    async delete(name) {
        if (!name) {
            console.error('Error: Name is required');
            return;
        }

        try {
            await api.delete(`/api/file/${name}`);
            console.log('Item deleted successfully');
        } catch (error) {
            console.error('Delete failed:', error.response?.data?.error || error.message);
        }
    },

    async rename(oldName, newName) {
        if (!oldName || !newName) {
            console.error('Error: Both old and new names are required');
            return;
        }

        try {
            await api.put(`/api/file/${oldName}/${newName}`);
            console.log('Rename successful');
        } catch (error) {
            console.error('Rename failed:', error.response?.data?.error || error.message);
        }
    },

    async mkdir(dirname) {
        if (!dirname) {
            console.error('Error: Directory name is required');
            return;
        }

        try {
            await api.post('/api/mkdir', { dirname });
            console.log('Directory created successfully');
        } catch (error) {
            console.error('Directory creation failed:', error.response?.data?.error || error.message);
        }
    },

    async list() {
        try {
            const response = await api.get('/api/list');
            console.log('\nDirectory contents:');
            response.data.forEach(item => {
                console.log(`${item.type === 'directory' ? 'd' : '-'} ${item.name}${item.type === 'directory' ? '/' : ''}`);
            });
        } catch (error) {
            console.error('List failed:', error.response?.data?.error || error.message);
        }
    },

    async lcd(dir) {
        if (!dir) {
            console.error('Error: Directory path is required');
            return;
        }

        try {
            const normalizedPath = path.resolve(dir);
            process.chdir(normalizedPath);
            console.log('Local directory changed to:', process.cwd());
        } catch (error) {
            console.error('Local directory change failed:', error.message);
        }
    },

    async lpwd() {
        console.log('Local working directory:', process.cwd());
    },

    async rcd(dir) {
        if (!dir) {
            console.error('Error: Directory path is required');
            return;
        }

        try {
            await api.post('/api/cd', { path: dir });
            console.log('Remote directory changed successfully');
        } catch (error) {
            console.error('Remote directory change failed:', error.response?.data?.error || error.message);
        }
    },

    async rpwd() {
        try {
            const response = await api.get('/api/pwd');
            console.log('Remote working directory:', response.data.path);
        } catch (error) {
            console.error('Failed to get remote working directory:', error.response?.data?.error || error.message);
        }
    },

    help() {
        console.log(`
Available commands:
    upload <file>                     Upload local file to server
    download <file>                   Download file from server
    delete <file/dir>                 Delete file or directory
    rename <old-name> <new-name>      Rename file or directory
    mkdir <dir>                       Create new directory
    list                             List directory contents
    lcd <dir>                        Change local directory
    lpwd                             Print local working directory
    rcd <dir>                        Change remote directory
    rpwd                             Print remote working directory
    help                             Show this help message
    exit                             Exit the program
        `);
    }
};

// 创建命令行界面
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: '> '
});

// 处理命令行输入
rl.prompt();
rl.on('line', async (line) => {
    const args = line.trim().split(/\s+/);
    const command = args[0]?.toLowerCase();

    try {
        if (command === 'exit') {
            rl.close();
            return;
        } else if (command === 'help') {
            commands.help();
        } else if (commands[command]) {
            await commands[command](...args.slice(1));
        } else if (command) {
            console.log('Unknown command. Type "help" for available commands.');
        }
    } catch (error) {
        console.error('Command failed:', error.message);
    }

    rl.prompt();
}).on('close', () => {
    console.log('Goodbye!');
    process.exit(0);
});

// 启动时显示欢迎信息
console.log(`
File Management System Client
Server: ${options.host}:${options.port}
User: ${options.user}
Type 'help' for available commands
`);